"use client";
import { Mime, UploadProps, JudgeRatio } from "./type";
import { AxiosProgressEvent } from "axios";
import { getSuffix, readFile, sleep } from "@/lib/util";
import { commonUploadReq } from "./api";
/**判断文件是否符合要求 */
export async function judgeFiles(files: FileList, allowTypes?: Mime[], maxSize?: number, judgeImageRatio?: JudgeRatio, judgeVideoRatio?: JudgeRatio) {
  if (!allowTypes && !maxSize && !judgeImageRatio) return;
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    judgeType(file, allowTypes)
    judgeSize(file, maxSize)
    await judgeImage(file, judgeImageRatio)
    await judgeVideo(file, judgeVideoRatio)
  }
}
/**判断是否通过类型校验 */
const judgeType = (file: File, allowTypes?: Mime[]) => {
  if (!allowTypes) return
  const typeFlag = allowTypes.some(k => {
    const pattern = new RegExp(`^${k.replace('*', '.*')}$`);
    return pattern.test(file.type || getSuffix(file.name));
  })

  if (!typeFlag) {
    throw `仅支持上传**${getAllowStrArr(allowTypes)}**类型`
  }
}
/**判断是否通过大小校验 */
const judgeSize = (file: File, maxSize?: number) => {
  if (!maxSize) return
  let sizeFlag = file.size / 1000 / 1024 <= parseFloat(maxSize + '');
  if (!sizeFlag) {
    throw `文件大小不能超过**${maxSize}MB**`
  }
}
/**判断图片满足分辨率及宽高。 不传递宽高则直接通过 */
const judgeImage = async (file: File, judgeImageRatio?: JudgeRatio) => {
  return new Promise<void>(async (resolve, reject) => {
    try {
      if (!judgeImageRatio) return resolve()
      const { maxWidth = Infinity, maxHeight = Infinity, scale } = judgeImageRatio
      const image = new Image();
      const dataUrl = await readFile<string>(file, "readAsDataURL")
      if (dataUrl) {
        image.onload = function () {
          const { width, height } = image
          if (width > maxWidth || height > maxHeight) {
            return reject(`图像尺寸超出限制，**最大 宽${maxWidth} 高${maxHeight}**，**当前 宽${image.width} 高${image.height}**`);
          }

          console.log('比例', height / width);
          if (scale && height / width > scale) {
            return reject(`图像比例超出限制，**要求的最大比例(高:宽)为${scale}**，**当前比例为${height / width}**`);
          }
          resolve()
        };
        image.src = dataUrl;
      } else {
        reject('读取失败')
      }
    } catch (error) {
      reject(error)
    }
  })

}
/**判断视频满足分辨率及宽高。 不传递宽高则直接通过 */
const judgeVideo = async (file: File, judgeVideoRatio?: JudgeRatio) => {
  return new Promise<void>(async (resolve, reject) => {
    try {
      if (!judgeVideoRatio) return resolve()
      const { maxWidth = Infinity, maxHeight = Infinity, scale } = judgeVideoRatio
      const video = document.createElement('video')
      const dataUrl = await readFile<string>(file, "readAsDataURL")
      if (dataUrl) {
        video.onloadedmetadata = function () {
          const { videoWidth, videoHeight } = video
          if (videoWidth > maxWidth || videoHeight > maxHeight) {
            return reject(`视频尺寸超出限制，**最大 宽${maxWidth} 高${maxHeight}**，**当前 宽${videoWidth} 高${videoHeight}**`);
          }

          console.log('比例', videoHeight / videoWidth);
          if (scale && videoHeight / videoWidth > scale) {
            return reject(`视频比例超出限制，**要求的最大比例(高:宽)为${scale}**，**当前比例为${videoHeight / videoWidth}**`);
          }
          resolve()
        };

        video.src = dataUrl
      } else {
        reject('读取失败')
      }
    } catch (error) {
      reject(error)
    }
  })
}
/**普通的 - 上传文件到服务器 */
export async function uploadToServer(url: string, files: FileList | File[], onUploadProgress?: (progressEvent: AxiosProgressEvent) => void) {
  try {
    const formData = new FormData();
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      formData.append(`file${i}`, file);
    }
    const res = await commonUploadReq(url, formData, onUploadProgress)
    return res
  } catch (error) {
    return Promise.reject(error)
  }

}


/**获得允许类型的文字提示数组。   
 * @example
 * getAllowStrArr(['image/jpeg', 'image/png']) ==> ['jpeg', 'png']
 */
export function getAllowStrArr(allowTypes: Mime[]) {
  return allowTypes.map((k) => {
    const arr = k.split("/")
    return arr[1] && arr[1] !== '*' ? arr[1] : arr[0]
  })
}





